/*
 *  Copyright (C) 2010 Glauco
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.swing.components.table;

import java.io.Serializable;
import java.util.List;
import java.util.logging.Level;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.balisunrise.application.Application;
import org.balisunrise.builder.FactoryException;
import org.balisunrise.common.Grid;
import org.balisunrise.common.events.LineSelectionEvent;
import org.balisunrise.common.listeners.GridSelectionListener;

/**
 *
 * @author glacuo
 */
public class ListSelectionListenerImpl implements ListSelectionListener{

    private JTable table;
    private List<GridSelectionListener> gridSelectionListeners;
    private LineSelectionEvent evt;
    private Grid grid;

    public ListSelectionListenerImpl(Grid grid) {
        this.grid = grid;
    }

    @Override
    public void valueChanged(ListSelectionEvent e) {

        if (e.getValueIsAdjusting())
            return;

        DefaultListSelectionModel dlsm =
            (DefaultListSelectionModel) e.getSource();

        int selectedIndex = dlsm.getMinSelectionIndex();

        fireLineActivatedEvent(e.getSource());

        if(table.getModel().getRowCount() == selectedIndex + 1)
            fireLastLineEvent();
    }

    public List<GridSelectionListener> getGridSelectionListeners() {
        return gridSelectionListeners;
    }

    public void setGridSelectionListeners(
            List<GridSelectionListener> gridSelectionListeners) {
        this.gridSelectionListeners = gridSelectionListeners;
    }

    public JTable getTable() {
        return table;
    }

    public void setTable(JTable table) {
        if (this.table != null)
            this.table.getSelectionModel().removeListSelectionListener(this);
        this.table = table;
        this.table.getSelectionModel().addListSelectionListener(this);
        this.table.getSelectionModel()
                .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    }

    public void fireLineActivatedEvent(Object source){

        Serializable entity = null;

        Object selectedRow = table.getSelectedRow();

        if(selectedRow instanceof Serializable)
            entity = (Serializable) selectedRow;

        evt = null;
        try{
            evt = Application.get().getFactory()
                    .createLineSelectedEvent(entity, grid);
        }catch (FactoryException fex){
            Application.get().getLogger().log(Level.SEVERE,
                    "ListSelectionListener não pode criar LineSelectedEvent",
                    fex);
        }
        if(evt == null)
            return ;

        for (GridSelectionListener gsl : gridSelectionListeners) {
            gsl.lineSelected(evt);
        }

        grid.getOwner().actionPerformed(evt);
    }

    public void fireLastLineEvent(){
        
        if(evt == null)
            return ;
        
        LineSelectionEvent llevt = null;
        try{
            llevt = Application.get().getFactory()
                    .createLastLineSelectedEvent(evt.getEntity(), grid);
        }catch (FactoryException fex){
            Application.get().getLogger().log(Level.SEVERE,
                    "ListSelectionListener não pode criar LastLineSelectedEvent",
                    fex);
        }
        if(llevt == null)
            return ;

        for (GridSelectionListener gsl : gridSelectionListeners) {
            gsl.lastLineSelected(llevt);
        }

        grid.getOwner().actionPerformed(llevt);
    }
}
